package com.yuanqunsoft.alimigration.dao.impl;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.yuanqunsoft.alimigration.dao.IReportDao;
import com.yuanqunsoft.alimigration.dao.support.Page;
import com.yuanqunsoft.alimigration.model.Report;

public class ReportDaoImpl extends HibernateDaoSupport implements IReportDao {

    @Override
    public boolean isNameExisted(String name) {
        try {
            String query = "from Report a where a.repName=?";
            List<Report> result = getHibernateTemplate().find(query, name);
            if (result != null) {
                if (!result.isEmpty()) {
                    return true;
                }
            }
            return false;
        } catch (RuntimeException re) {
            throw re;
        }
    }

    @Override
    public void save(Report instance) {
        try {
            getHibernateTemplate().saveOrUpdate(instance);
        } catch (RuntimeException re) {
            throw re;
        }
    }

    @Override
    public void delete(Report instance) {
        try {
            getHibernateTemplate().delete(instance);
        } catch (RuntimeException re) {
            throw re;
        }
    }

    @Override
    public Report findById(Integer id) {
        try {
            Report instance = (Report) getHibernateTemplate().get(Report.class, id);
            return instance;
        } catch (RuntimeException re) {
            throw re;
        }
    }

    @Override
    public List findByApplicationId(Integer id) {
        try {
            String query = "from Report a where a.application.appId=?";
            List<Report> result = getHibernateTemplate().find(query, id);
            return result;
        } catch (RuntimeException re) {
            throw re;
        }
    }

    @Override
    public List findByExample(Report instance) {
        try {
            List<Report> result = getHibernateTemplate().findByExample(instance);
            return result;
        } catch (RuntimeException re) {
            throw re;
        }
    }

    @Override
    public List findAll() {
        try {
            String query = "from Report";
            return getHibernateTemplate().find(query);
        } catch (RuntimeException re) {
            throw re;
        }
    }

    @Override
    public boolean hqlExcute(String hql, Object... values) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public List<Report> hqlQuery(String hql, Object... values) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public <Report> Page<Report> pagedQuery(String hql, int pageNo, int pageSize, Object... values) {

        String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
        List<Report> countlist = this.getHibernateTemplate().find(countQueryString, values);
        long totalCount = (Long) countlist.get(0);

        if (totalCount < 1)
            return new Page<Report>();
        // 当前页的开始数据索引
        long startIndex = Page.getStartOfPage(pageNo, pageSize);
        Query query = this.createQuery(hql, values);
        List<Report> list = query.setFirstResult((int) startIndex).setMaxResults(pageSize).list();

        return new Page<Report>(startIndex, totalCount, pageSize, list);
    }

    @Override
    public Page<Report> pagedQueryByStartNo(String hql, int startNo, int pageSize, Object... values) {
        String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
        List<Long> countlist = getHibernateTemplate().find(countQueryString, values);
        long totalCount = (Long) countlist.get(0);
        if (totalCount < 1)
            return new Page<Report>();
        int startIndex = startNo;
        Query query = createQuery(hql, values);
        List<Report> list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
        return new Page<Report>(startIndex, totalCount, pageSize, list);
    }

    @Override
    public List<Report> findByNamedParams(String hql, String[] paramNames, Object... values) {
        // TODO Auto-generated method stub
        return null;
    }

    private static String removeOrders(String hql) {
        Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(hql);
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            m.appendReplacement(sb, "");
        }
        m.appendTail(sb);
        return sb.toString();
    }

    private static String removeSelect(String hql) {
        int beginPos = hql.toLowerCase().indexOf("from");
        return hql.substring(beginPos);
    }

    public Query createQuery(String hql, Object... values) {
        // Query query = this.getSession(false).createQuery(hql);
        Session session = this.getHibernateTemplate().getSessionFactory().openSession();
        Query query = session.createQuery(hql);
        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                query.setParameter(i, values[i]);
            }
        }
        return query;
    }

    @Override
    public void deleteByApplicationId(Integer appId) {
        // TODO Auto-generated method stub
        try{
            List<Report> reportList = this.findByApplicationId(appId);
            for(Report r : reportList){
                this.delete(r);
            }
        }catch(RuntimeException re){
            throw re;
        }
    }

}
